/**
 * eknows base components
 *
 * Copyright Leon
 * Date 2017-08-30
 */
(function( factory ) {
	if ( typeof define === "function" && define.amd ) {
		//AMD模块调用方式
		define( [ "jquery" ], factory );
	} else {
		//浏览器直接调用
		factory( jQuery );
	}
}(function( $ ) {

//全局UI对象集合
$.eknowsui = $.eknowsui || {};

$.extend( $.eknowsui, {
	version: "1.0.0",

	keyCode: {
		BACKSPACE: 8,
		COMMA: 188,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		LEFT: 37,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
});

//扩展jquery函数
$.fn.extend({
	
	//查询文档流中最近的可滚动父级元素
	scrollParent: function( includeHidden ) {
		var position = this.css( "position" ),
			excludeStaticParent = position === "absolute",  //绝对定位时，静态定位元素不能算成父级元素
			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,	//可滚动判断正则表达式
			scrollParent = this.parents().filter( function() {
				var parent = $( this );
				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
					return false;
				}
				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
			}).eq( 0 );

		//fixed定位始终以document为父级参考
		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
	},

	// 生成UI组件的唯一ID
	//   此处增量ID存储在闭包变量中，重新加载页面会清空为0
	uniqueId: (function() {
		var uuid = 0;

		return function() {
			return this.each(function() {
				if ( !this.id ) {
					this.id = "eknowsui-id-" + ( ++uuid );
				}
			});
		};
	})(),

	//移除UI组件的ID编号
	removeUniqueId: function() {
		return this.each(function() {
			if ( /^eknowsui-id-\d+$/.test( this.id ) ) {
				$( this ).removeAttr( "id" );
			}
		});
	},
	
	//禁用元素选择：比如在拖动元素时不希望选择内部元素
	disableSelection: (function() {
		var eventType = "onselectstart" in document.createElement( "div" ) ?
			"selectstart" :
			"mousedown";

		return function() {
			return this.bind( eventType + ".eknowsui-disableSelection", function( event ) {
				event.preventDefault();
			});
		};
	})(),

	//启用元素选择
	enableSelection: function() {
		return this.unbind( ".eknowsui-disableSelection" );
	}
});

//判断元素是否可获取焦点
function focusable( element, isTabIndexNotNaN ) {
	var map, mapName, img,
		nodeName = element.nodeName.toLowerCase();
	if ( "area" === nodeName ) {
		map = element.parentNode;
		mapName = map.name;
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
			return false;
		}
		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
		return !!img && visible( img );
	}
	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
		!element.disabled :
		"a" === nodeName ?
			element.href || isTabIndexNotNaN :
			isTabIndexNotNaN) &&
		
		visible( element );
}

//判断元素时候可见
//	元素及其父元素都可见才判断为可见
function visible( element ) {
	return $.expr.filters.visible( element ) &&
		!$( element ).parents().addBack().filter(function() {
			return $.css( this, "visibility" ) === "hidden";
		}).length;
}

//扩展jquery伪类选择器
$.extend( $.expr[ ":" ], {
	//选出有特定数据的元素
	//只支持jquery >1.8，具体用法参考sizzle API
	data: $.expr.createPseudo(function( dataName ) {
			return function( elem ) {
				return !!$.data( elem, dataName );
			};
		}),

	//是否可获取焦点
	focusable: function( element ) {
		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
	},

	//是否可获取TAB键
	tabbable: function( element ) {
		var tabIndex = $.attr( element, "tabindex" ),
			isTabIndexNaN = isNaN( tabIndex );
		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
	}
});

$.eknowsui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );

//附加的ui插件
$.eknowsui.plugin = {
	//注册查询模块
	add: function(module, option, set) {
		var i,
			proto = $.ui[ module ].prototype;
		
		for ( i in set ) {
			proto.plugins[ i ] = proto.plugins[ i ] || [];
			proto.plugins[ i ].push( [ option, set[ i ] ] );
		}
	},
	//调用查询
	call: function(instance, name, args, allowDisconnected) {
		var i,
		set = instance.plugins[ name ];

		if ( !set ) {
			return;
		}
	
		//判断DOM调用是否可以脱离文档流
		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
			return;
		}
	
		//如果添加的插件没有设置option选项，则不进行调用（option选项为上一方法参数）
		for ( i = 0; i < set.length; i++ ) {
			if ( instance.options[ set[ i ][ 0 ] ] ) {
				set[ i ][ 1 ].apply( instance.element, args );
			}
		}
	}
};

}));